package rad.framework.mda.properties.views;

import java.util.ArrayList;

import rad.framework.mda.properties.AbstractTabbedPropertySection;
import rad.framework.mda.properties.Activator;

import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.provider.IItemLabelProvider;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
import org.eclipse.emf.edit.provider.IItemPropertySource;
import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;
import org.eclipse.gmf.runtime.common.ui.services.properties.PropertiesService;
import org.eclipse.jface.util.Assert;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.views.properties.IPropertySource;
import org.eclipse.ui.views.properties.tabbed.ITabbedPropertyConstants;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
import org.eclipse.uml2.uml.TypedElement;
import org.eclipse.uml2.uml.UMLPackage;

/**
 * @author boudyacho
 *
 */
public class TypedElementSection extends AbstractTabbedPropertySection {

	private Text typeText;

	private TypedElement umlElement;

	private CLabel fontLabel;
	
	public void setInput(IWorkbenchPart part, ISelection selection) {
		super.setInput(part, selection);
		Assert.isTrue(selection instanceof IStructuredSelection);
		Object input = ((IStructuredSelection) selection).getFirstElement();
		Assert.isTrue(input instanceof TypedElement);
		this.umlElement = (TypedElement) input;
	}

	public void createControls(Composite parent,TabbedPropertySheetPage aTabbedPropertySheetPage) {
		
		super.createControls(parent, aTabbedPropertySheetPage);

		Composite composite = getWidgetFactory().createFlatFormComposite(parent);
		FormData data;

		Shell shell = new Shell();
		GC gc = new GC(shell);
		gc.setFont(shell.getFont());
		Point point = gc.textExtent("");
		int buttonHeight = point.y + 5;
		gc.dispose();
		shell.dispose();

		fontLabel = getWidgetFactory().createCLabel(composite, "Type:");
		typeText = getWidgetFactory().createText(composite, "");
		typeText.setEditable(false);
		Button typeButton = getWidgetFactory().createButton(composite,"...", SWT.PUSH);
		typeButton.addSelectionListener(new SelectionAdapter() {

			public void widgetSelected(SelectionEvent event) {

				TypeListSelectionDialog dialog = new TypeListSelectionDialog(
						PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), new ArrayList(getItemPropertyDescriptor().getChoiceOfValues(umlElement)), new ILabelProvider() {

							public Image getImage(Object element) {
								Object u = getAdapter(element).getImage(element);
								return ExtendedImageRegistry.getInstance().getImage(u);
							}

							public String getText(Object element) {
								return getAdapter(element).getText(element);
							}

							public void addListener(
									ILabelProviderListener listener) {
							}

							public void dispose() {
							}

							public boolean isLabelProperty(Object element,
									String property) {
								return false;
							}

							public void removeListener(
									ILabelProviderListener listener) {
							}
						});
				dialog.open();
				Object[] results = dialog.getResult();

				if (results != null) {
					IPropertySource properties = (IPropertySource) getPropertySource(umlElement);
					properties.setPropertyValue(
							UMLPackage.Literals.TYPED_ELEMENT__TYPE, results[0]);
					typeText.setText(getText(results[0]));
					fontLabel.setImage(getImage(results[0]));
				}
			}
		});

		data = new FormData();
		data.left = new FormAttachment(0, 0);
		data.right = new FormAttachment(typeText,-ITabbedPropertyConstants.HSPACE);
		data.top = new FormAttachment(0, 0);
		fontLabel.setLayoutData(data);

		data = new FormData();
		data.left = new FormAttachment(0, STANDARD_LABEL_WIDTH);
		data.right = new FormAttachment(typeButton,-ITabbedPropertyConstants.HSPACE);
		data.top = new FormAttachment(0, 0);
		typeText.setLayoutData(data);

		data = new FormData();
		data.right = new FormAttachment(100, 0);
		data.top = new FormAttachment(0, 0);
		data.height = buttonHeight;
		typeButton.setLayoutData(data);

	}

	public void refresh() {
		IPropertySource properties = getPropertySource(umlElement);
		Object value = properties.getPropertyValue(UMLPackage.Literals.TYPED_ELEMENT__TYPE);
		if (value != null) {
			typeText.setText(getText(value));
			fontLabel.setImage(getImage(value));
		} else {
			typeText.setText("");
			fontLabel.setImage(null);
		}
	}

	protected IPropertySource getPropertySource(Object o) {
		return PropertiesService.getInstance().getPropertySource(o);
	}

	protected IItemPropertyDescriptor getItemPropertyDescriptor() {
		IItemPropertySource ps = (IItemPropertySource) Activator.getDefault().getItemProvidersAdapterFactory().adapt(umlElement,IItemPropertySource.class);
		Object propertyId = "Typed Elementtype : Type";
		IItemPropertyDescriptor pd = ps.getPropertyDescriptor(umlElement,propertyId);
		return pd;
	}

	protected IItemLabelProvider getAdapter(Object element) {
		return (IItemLabelProvider) Activator.getDefault().getItemProvidersAdapterFactory().adapt(element,IItemLabelProvider.class);
	}

	protected Image getImage(Object element) {
		Object u = getAdapter(element).getImage(element);
		return ExtendedImageRegistry.getInstance().getImage(u);
	}

	protected String getText(Object element) {
		return getAdapter(element).getText(element);
	}

	@Override
	protected EStructuralFeature getFeature() {
		return UMLPackage.Literals.TYPED_ELEMENT__TYPE;
	}

	@Override
	protected String getLabelText() {
		return "Type:";
	}

}
